package indi.jp.project.process.service.impl;

import indi.jp.project.center.entity.Task;
import indi.jp.project.center.service.TaskService;
import indi.jp.project.core.entity.JsonResult;
import indi.jp.project.core.util.SerialUtil;
import indi.jp.project.process.dao.FlowTaskDAO;
import indi.jp.project.process.entity.*;
import indi.jp.project.process.service.FlowTaskNotifyService;
import indi.jp.project.process.service.FlowTaskService;
import org.springframework.beans.BeanUtils;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import javax.annotation.Resource;
import java.sql.SQLException;
import java.util.LinkedList;
import java.util.List;
import java.util.Map;

/**
 * 原始流程代码备份
 *
 * @author jiangping
 * @date 2022/5/28
 */
//@Service
public class FlowTaskServiceBack implements FlowTaskService {

    @Resource
    private FlowTaskDAO flowTaskDAO;

    @Resource
    private SerialUtil serialUtil;

    @Resource
    private TaskService taskService;

    @Resource
    Map<String, FlowTaskNotifyService> map;

    @Override
    public JsonResult queryTaskFlow(String taskId) throws Exception {
        LinkedList<FlowTask> list = flowTaskDAO.queryTaskFlow(taskId);
        return JsonResult.success(list);
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public void saveTaskFlow(String taskId, List<FlowTask> list) throws Exception {
        if (list != null && list.size() > 0) {
            flowTaskDAO.deleteTaskFlow(taskId);
            list.forEach(flowTask -> {
                flowTask.setId(String.valueOf(serialUtil.nextId()));
                flowTask.setTaskId(taskId);
            });
            flowTaskDAO.saveTaskFlow(list);
        }
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public JsonResult flowSubmit(FlowTaskParam flowTaskParam) throws Exception {
        // 获取当前和下一步流程
        FlowTaskStep flowTaskStep = getFlowStep(flowTaskParam.getState(), flowTaskParam.getTaskId(), 0);
        doSubmit(flowTaskStep, flowTaskParam);
        return JsonResult.success("操作成功");
    }

    @Override
    public JsonResult flowAgree(FlowTaskParam flowTaskParam) throws Exception {
        return null;
    }

    @Override
    public JsonResult flowReject(FlowTaskParam flowTaskParam) throws Exception {
        // 获取当前和下一步流程
        FlowTaskStep flowTaskStep = getFlowStep(flowTaskParam.getState(), flowTaskParam.getTaskId(), 1);
        doReject(flowTaskStep, flowTaskParam);
        return JsonResult.success("操作成功");
    }

    @Override
    public JsonResult flowRevoke(FlowTaskParam flowTaskParam) throws Exception {
        return null;
    }

    /**
     * 保存流程
     */
    private void doSubmit(FlowTaskStep flowTaskStep, FlowTaskParam flowTaskParam) throws Exception {
        // 创建用于更新任务表流程的实体
        FlowTaskParam taskFlowEntity = new FlowTaskParam();
        BeanUtils.copyProperties(flowTaskStep.getNextStep(), taskFlowEntity);
        // 根据流程类型确定操作的表
        String typeCode = flowTaskParam.getFlowTypeCode();
        String tableName = FlowTypeEnum.valueOf(typeCode).getTableName();
        taskFlowEntity.setTableName(tableName);
        flowTaskDAO.updateTaskFlow(taskFlowEntity);
        // 保存任务操作历史
        FlowTaskHistory flowTaskHistory = new FlowTaskHistory();
        BeanUtils.copyProperties(flowTaskParam, flowTaskHistory);
        BeanUtils.copyProperties(flowTaskStep.getCurrentStep(), flowTaskHistory);
        flowTaskHistory.setId(String.valueOf(serialUtil.nextId()));
        flowTaskHistory.setNodeName(flowTaskStep.getCurrentStep().getName());
        flowTaskDAO.saveOperationHistory(flowTaskHistory);
        // 保存到任务中心
//        Task task = flowTaskDAO.queryTaskInfo(tableName, flowTaskParam.getTaskId());
//        task.setId(String.valueOf(serialUtil.nextId()));
//        task.setTaskName(FlowTypeEnum.valueOf(typeCode).getFlowName());
//        task.setTaskState(flowTaskStep.getNextStep().getState());
//        task.setTaskStateName(flowTaskStep.getNextStep().getStateName());
//        task.setTaskHandler(flowTaskStep.getNextStep().getHandler());
//        task.setTaskHandlerName(flowTaskStep.getNextStep().getHandlerName());
//        task.setCreateBy(flowTaskParam.getCreateBy());
//        taskService.generateTask(task);
        // 如果对应的Service需要通知，则调用通知方法
        FlowTaskNotifyService flowTaskNotifyService = map.get(FlowTypeEnum.valueOf(typeCode).getServiceName());
        if (flowTaskNotifyService != null) {
            FlowTaskNotifyDTO flowTaskNotifyDTO = new FlowTaskNotifyDTO();
            flowTaskNotifyDTO.setTaskId(flowTaskParam.getTaskId());
            flowTaskNotifyDTO.setOperation(flowTaskParam.getOperation());
            flowTaskNotifyDTO.setCurrentState(flowTaskStep.getCurrentStep().getState());
            flowTaskNotifyDTO.setNextState(flowTaskStep.getNextStep().getState());
            flowTaskNotifyDTO.setFlowType(flowTaskParam.getFlowTypeCode());
            flowTaskNotifyDTO.setHandler(flowTaskParam.getHandler());
            flowTaskNotifyDTO.setHandlerName(flowTaskParam.getHandlerName());
            flowTaskNotifyDTO.setCreateBy(flowTaskParam.getCreateBy());
            flowTaskNotifyService.notify(flowTaskNotifyDTO);
        }
    }

    /**
     * 驳回流程
     */
    private void doReject(FlowTaskStep flowTaskStep, FlowTaskParam flowTaskParam) throws SQLException {
        // 创建用于更新任务表流程的实体
        FlowTaskParam taskFlowEntity = new FlowTaskParam();
        // 根据流程类型确定操作的表
        String typeCode = flowTaskParam.getFlowTypeCode();
        String tableName = FlowTypeEnum.valueOf(typeCode).getTableName();
        taskFlowEntity.setTableName(tableName);
        taskFlowEntity.setTaskId(flowTaskParam.getTaskId());
        taskFlowEntity.setState(0);
        flowTaskDAO.updateTaskFlow(taskFlowEntity);
        // 保存任务操作历史
        FlowTaskHistory flowTaskHistory = new FlowTaskHistory();
        BeanUtils.copyProperties(flowTaskParam, flowTaskHistory);
        BeanUtils.copyProperties(flowTaskStep.getCurrentStep(), flowTaskHistory);
        flowTaskHistory.setId(String.valueOf(serialUtil.nextId()));
        flowTaskHistory.setNodeName(flowTaskStep.getCurrentStep().getName());
        flowTaskDAO.saveOperationHistory(flowTaskHistory);
        // 结束任务中心任务
        Task task = new Task();
        task.setTaskId(flowTaskParam.getTaskId());
        task.setTaskState(0);
        taskService.generateTask(task);
    }

    /**
     * 获取任务流程
     *
     * @param currentState 当前状态
     * @param taskId       任务ID
     * @param type         类型 0:提交/通过，1:驳回
     */
    private FlowTaskStep getFlowStep(int currentState, String taskId, int type) throws SQLException {
        // 查询任务流程
        LinkedList<FlowTask> list = flowTaskDAO.queryTaskFlow(taskId);
        FlowTaskStep flowTaskStep = new FlowTaskStep();
        // 是否已获取当前状态，已获取则可以判断下一步状态
        boolean currentAcquired = false;
        for (int i = 0; i < list.size(); i++) {
            FlowTask step = list.get(i);
            // 如果状态为99，则下一步直接结束
            if (step.getState() == 99) {
                flowTaskStep.setNextStep(step);
                break;
            }
            // 状态相等则给当前状态赋值，并标记已获取当前状态
            if (step.getState() == currentState) {
//                if (currentState != 0) {
//                    flowTaskStep.setLastStep(list.get(i - 1));
//                }
                flowTaskStep.setCurrentStep(step);
                // 如果是驳回，则获取当前流程后直接结束循环
                if (type == 1) {
                    break;
                }
                currentAcquired = true;
                continue;
            }
            // 如果已获取当前状态，获取后续系统节点，则下一步为需系统处理的节点
            if (currentAcquired && step.getCategory() == 0) {
                flowTaskStep.setNextStep(step);
                break;
            }
            // 如果已获取当前状态，则判断下一步处理人不为空的节点，不包含结束状态
            if (currentAcquired && step.getState() != 99 && !"".equals(step.getHandler())) {
                flowTaskStep.setNextStep(step);
                break;
            }
        }
        return flowTaskStep;
    }

    @Override
    public JsonResult flowCancel(FlowTaskParam flowTaskParam) throws Exception {
        return JsonResult.success("操作成功");
    }

    @Override
    public JsonResult loadFlowHistory(String taskId) throws Exception {
        List<FlowTaskHistory> list = flowTaskDAO.queryTaskFlowHistory(taskId);
        return JsonResult.success(list);
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public void deleteFlowByTaskId(String taskId) throws Exception {
        flowTaskDAO.deleteTaskFlow(taskId);
        flowTaskDAO.deleteFlowHistoryByTaskId(taskId);
        taskService.deleteByTaskId(taskId);
    }

}
